//============================================================================================
/**
 * @file	pkthln_poke_select.c
 * @brief	ポケスロン参加ポケモン選択アプリ
 * @author	Nozomu Saito
 */
//============================================================================================

#include "common.h"
#include "../pokethlon_common.h"

#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/snd_tool.h"
#include "system/touch_subwindow.h"
#include "system/wipe.h"
#include "system/clact_tool.h"

#include "gflib/touchpanel.h"

#include "poketool/boxdata.h"
#include "poketool/pokeparty.h"
#include "poketool/monsno.h"
#include "poketool/pokeicon.h"
#include "poketool/poke_tool.h"
#include "poketool/poke_tool_def.h"		/* ##### */
#include "savedata/savedata.h"


#include "../../../fushigi/mystery.naix"


#include "system/wordset.h"
#include "system/msgdata_util.h"
#include "system/fontproc.h"
#include "system/pmfprint.h"

#include "application/poke_select.h"
#include "application/p_status.h"
#include "pkth_sel_sub.h"

#include "communication/wm_icon.h"	//for WirelessIconEasyPokethlon

//** CharManager PlttManager用 **//
#define CHAR_CONT_NUM				(40)
#define CHAR_VRAMTRANS_MAIN_SIZE		(64*1024)
#define CHAR_VRAMTRANS_SUB_SIZE		(16*1024)
#define PLTT_CONT_NUM				(20)

#define POKEMON_SELECT_MAX			(3)
#define BOX_NUM_MAX					(18+1)		//ボックスの数（ボックス＋手持ち）

#define	FONT_PALNO_NORMAL	(15)	/* ノーマルパレット */

typedef struct PKTHLN_POKE_SEL_WORK_tag
{
	GF_BGL_INI *bgl;
	int Seq;
	POKE_SELECT_WORK_PTR PokeSelPtr;
	PSS_CNT_PTR				PssCntPtr;
	SELECT_RESULT_INFO	 SelectResult[POKEMON_SELECT_MAX];
	BOOL SelectCancel;
	SAVEDATA	*SaveData;
	int CourseID;
}PKTHLN_POKE_SEL_WORK;

enum {
	POKE_SELECT_SCREEN_INIT,
	POKE_SELECT_POKE_ICON_SET,
	POKE_SELECT_WIPE_IN_WAIT,
	POKE_SELECT_MAIN,
	POKE_SELECT_END,
	POKE_SELECT_BLACK_OUT_WAIT,
};

static BOOL FuncInit(/*POKETHLON_HEADER *header*/PROC * proc);

static BOOL PokeSelectInit(PROC * proc);
static void SetVRAMBank(void);
static void SetUpBGSys(GF_BGL_INI * ini);
static void InitCharPlttManager(void);
static void InitOAM(PKTHLN_POKE_SEL_WORK *work);
static void VBlankFunc( void * work );
static BOOL GetBoxPokeData(void *pBoxData, const int inBoxNum, const int inIndex, BOX_POKE_DATA *outData);
static BOOL GetBoxPokeData2(void *pBoxData, const int inBoxNum, const int inIndex, BOX_POKE_DATA *outData);

static void GetBoxName(STRBUF * msg, void *pBoxData, int inBoxNumber);

static void SetResultData(PKTHLN_POKE_SEL_WORK *work, PKTHLN_LINK_DATA *pLinkData);
static void GetSpec( POKEPARTY *ppt, const u8 inPos, POKE_SPEC *outSpec);
static void GetSpecPPP( POKEMON_PASO_PARAM* param, POKE_SPEC *outSpec);
static void GetMaxSpecPPP( POKEMON_PASO_PARAM* param, POKE_SPEC *outSpec);

#ifdef PM_DEBUG
static void DebugGetSpec(POKE_SPEC *outSpec, const u8 inIdx);
#endif

static void	 CallbackFunc( int inBoxIdx, int inBoxPos, void *CallBackWk );

static void SetPkthlnParam(	const POKE_SPEC *inBase, const POKE_SPEC *inSpec,
							const PM_CONDITION *inCnd, PSS_REDRAW_INFO *outInfo);

PROC_RESULT PKTHLN_PokeSelect_Init(PROC * proc, int * seq);
PROC_RESULT PKTHLN_PokeSelect_Main(PROC * proc, int * seq);
PROC_RESULT PKTHLN_PokeSelect_End(PROC * proc, int * seq);

#ifdef PM_DEBUG
extern DEBUG_PKTHLN_WORK DebugPkthlnWk;
#endif

//--------------------------------------------------------------------------------------------
/**
 * ポケスロン参加ポケモン選択プロセス	初期化処理
 *
 * @param	proc			プロセス
 * @param	seq				シーケンス
 *
 * @return	PROC_RESULT		プロセスリターンコード
 */
//--------------------------------------------------------------------------------------------
PROC_RESULT PKTHLN_PokeSelect_Init(PROC * proc, int * seq)
{
	if ( FuncInit(proc) ){
		return PROC_RES_FINISH;
	}
	return PROC_RES_CONTINUE;
}

//--------------------------------------------------------------------------------------------
/**
 * ポケスロン参加ポケモン選択プロセス	メイン処理
 *
 * @param	proc			プロセス
 * @param	seq				シーケンス
 *
 * @return	PROC_RESULT		プロセスリターンコード
 */
//--------------------------------------------------------------------------------------------
PROC_RESULT PKTHLN_PokeSelect_Main(PROC * proc, int * seq)
{
	int selno, seltype;

	PKTHLN_POKE_SEL_WORK *work = PROC_GetWork(proc);
//	OS_Printf("ポケモン選択画面メイン\n");
	switch(work->Seq){
	case POKE_SELECT_SCREEN_INIT:
		work->Seq = POKE_SELECT_POKE_ICON_SET;
		break;
	case POKE_SELECT_POKE_ICON_SET:
#if 0		//仕様変更で不要になった
		//開始時に、上画面セットアップ
		PkthSelSub_SetFirstDraw(work->PssCntPtr);
#endif
		//ワイプスタート
		WIPE_SYS_Start(WIPE_PATTERN_WMS, WIPE_TYPE_FADEIN, WIPE_TYPE_FADEIN,
				WIPE_FADE_BLACK,WIPE_DEF_DIV,WIPE_DEF_SYNC,HEAPID_POKETHLON);
		work->Seq = POKE_SELECT_WIPE_IN_WAIT;
		break;
	case POKE_SELECT_WIPE_IN_WAIT:		//ワイプ待ち
		if ( WIPE_SYS_EndCheck() ){
			work->Seq = POKE_SELECT_MAIN;
		}
		break;
	case POKE_SELECT_MAIN:
		{
			SELECT_MAIN_RC rc;
			//OS_Printf("メイン処理中\n");
			rc = POKESEL_Main(work->PokeSelPtr);
			if ( rc == SELECT_MAIN_RC_END ){
				work->SelectCancel = FALSE;
				work->Seq = POKE_SELECT_END;
			}else if ( rc == SELECT_MAIN_RC_CANCEL ){
				work->SelectCancel = TRUE;
				work->Seq = POKE_SELECT_END;
			}
		}
		break;
	case POKE_SELECT_END:
		//ブラックアウト
		WIPE_SYS_Start(WIPE_PATTERN_WMS, WIPE_TYPE_FADEOUT, WIPE_TYPE_FADEOUT,
				WIPE_FADE_BLACK,WIPE_DEF_DIV,WIPE_DEF_SYNC,HEAPID_POKETHLON);
		work->Seq = POKE_SELECT_BLACK_OUT_WAIT;
		break;
	case POKE_SELECT_BLACK_OUT_WAIT:
		if ( WIPE_SYS_EndCheck() ){
			PKTHLN_LINK_DATA *link_data = PROC_GetParentWork( proc );
			OS_Printf("選択終了\n");
			//親アプリに選択結果を格納
			SetResultData(work, link_data);
			return PROC_RES_FINISH;
		}
		break;
	}

	//ポケモン選択
	//描画
	POKESEL_Draw(work->PokeSelPtr);
	PkthSelSub_Draw(work->PssCntPtr);

	return PROC_RES_CONTINUE/*PROC_RES_FINISH*/;
}

//--------------------------------------------------------------------------------------------
/**
 * ポケスロン参加ポケモン選択プロセス	終了処理
 *
 * @param	proc			プロセス
 * @param	seq				シーケンス
 *
 * @return	PROC_RESULT		プロセスリターンコード
 */
//--------------------------------------------------------------------------------------------
PROC_RESULT PKTHLN_PokeSelect_End(PROC * proc, int * seq)
{
	PKTHLN_POKE_SEL_WORK *work = PROC_GetWork(proc);

	OS_Printf("ポケモン選択画面終了処理\n");

	//Ｖブランク関数停止
	sys_VBlankFuncChange( NULL, NULL );

	//上画面コントローラ解放
	PkthSelSub_Free(work->PssCntPtr);

	//ポケモン選択画面用ワーク解放
	POKESEL_Free( work->PokeSelPtr );

	//フォント削除
	FontProc_UnloadFont(FONT_BUTTON);

	//OAMレンダラー破棄
	REND_OAM_Delete();
	// リソース解放
	DeleteCharManager();
	DeletePlttManager();

	//BGL解放
	sys_FreeMemoryEz(work->bgl);

	//ポケモン選択メモリ解放
	sys_FreeMemoryEz(work);

	return PROC_RES_FINISH;
}

//--------------------------------------------------------------------------------------------
/**
 * 初期化
 *
 * @param	proc		プロックポインタ
 *
 * @return	BOOL		TRUE:終了		FALSE:継続
 */
//--------------------------------------------------------------------------------------------
static BOOL FuncInit(PROC * proc)
{
	PKTHLN_LINK_DATA *link_data = PROC_GetParentWork( proc );
	OS_Printf("ポケモン選択画面初期化中\n");

	do{
		BOOL rc;
		rc = PokeSelectInit(proc);
		if (rc){
			return TRUE;
		}
	}while(link_data->Header->GameType == PKTHLN_GAME_ALONE);//通信中ではないなら、処理を続ける

	return FALSE;
}

//--------------------------------------------------------------------------------------------
/**
 * 初期化
 *
 * @param	proc		プロックポインタ
 *
 * @return	BOOL		TRUE:終了		FALSE:継続
 */
//--------------------------------------------------------------------------------------------
static BOOL PokeSelectInit(PROC * proc)
{
	PKTHLN_POKE_SEL_WORK *work;
	PKTHLN_LINK_DATA *link_data = PROC_GetParentWork( proc );
	POKETHLON_HEADER *header = link_data->Header;
	//ポケモン選択メモリアロケーション
	work = PROC_AllocWork(proc, sizeof(PKTHLN_POKE_SEL_WORK), HEAPID_POKETHLON);
	//ワークはゼロクリア
	memset(work, 0, sizeof(PKTHLN_POKE_SEL_WORK));

	//BGLアロケーション
	work->bgl = GF_BGL_BglIniAlloc(HEAPID_POKETHLON);
	//セーブワークポインタセット
	work->SaveData = header->SaveData;
	//コースセット
	work->CourseID = link_data->CourseID;
	//ＶＲＡＭ割り当て
	SetVRAMBank();

	//ポケモン選択画面用ワーク確保
	work->PokeSelPtr = POKESEL_Alloc(HEAPID_POKETHLON, POKEMON_SELECT_MAX, BOX_NUM_MAX );
	//上画面コントローラアロケーション
	work->PssCntPtr = PkthSelSub_Alloc(HEAPID_POKETHLON);

	//ＢＧセットアップ
	SetUpBGSys(work->bgl);
	//キャラ・パレットマネージャ初期化
	InitCharPlttManager();
	//ＯＡＭ初期化
	InitOAM(work);

	{
		BOOL cancel = FALSE;
		if ( link_data->Header->GameType == PKTHLN_GAME_ALONE ){
			cancel = TRUE;
		}
		//ポケモン選択画面アプリ初期化
		POKESEL_Init( work->PokeSelPtr, work->bgl,
				SaveData_GetBoxData( header->SaveData ),
				SaveData_GetTemotiPokemon( header->SaveData ),
				FALSE, FALSE,
				cancel,
				MYPARTY_BOX,
				GetBoxPokeData2,
				GetBoxName,
				work->SelectResult,
				CallbackFunc,
				work);
	}

	//通信アイコン
	WirelessIconEasyPokethlon( NNS_G2D_VRAM_TYPE_2DSUB );

	{
		//上画面初期化
		PkthSelSub_Init( work->PssCntPtr, work->bgl, work->CourseID, header->AllStar );
	}

	//Ｖブランク関数実行開始
	sys_VBlankFuncChange( VBlankFunc, work );

	//シーケンス初期化
	work->Seq = POKE_SELECT_SCREEN_INIT;

	//メッセージプリント
	MSG_PrintInit();
	/* メッセージのフォントカラーを設定 */
	SystemFontPaletteLoad( PALTYPE_MAIN_BG, FONT_PALNO_NORMAL * 32, HEAPID_POKETHLON);
	// ボタン用フォントの読み込み
	FontProc_LoadFont(FONT_BUTTON, HEAPID_POKETHLON);

	return TRUE;
}

//----------------------------------------------------------------------------
/**
 *	@brief	VRAM割り当て
 *
 *	@param	none
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void SetVRAMBank(void)
{
	GF_BGL_DISPVRAM tbl = {
		GX_VRAM_BG_128_A,				// メイン2DエンジンのBG
		GX_VRAM_BGEXTPLTT_NONE,			// メイン2DエンジンのBG拡張パレット

		GX_VRAM_SUB_BG_128_C,			// サブ2DエンジンのBG
		GX_VRAM_SUB_BGEXTPLTT_NONE,		// サブ2DエンジンのBG拡張パレット

		GX_VRAM_OBJ_64_E,				// メイン2DエンジンのOBJ
		GX_VRAM_OBJEXTPLTT_NONE,		// メイン2DエンジンのOBJ拡張パレット

		GX_VRAM_SUB_OBJ_16_I,			// サブ2DエンジンのOBJ
		GX_VRAM_SUB_OBJEXTPLTT_NONE,	// サブ2DエンジンのOBJ拡張パレット

		GX_VRAM_TEX_0_B,				// テクスチャイメージスロット
		GX_VRAM_TEXPLTT_01_FG			// テクスチャパレットスロット
	};

	GF_Disp_SetBank( &tbl );

}

//----------------------------------------------------------------------------
/**
 *	@brief	BGシステムセットアップ
 *
 *	@param	ini		BGL
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void SetUpBGSys(GF_BGL_INI * ini)
{
	{	/* BG SYSTEM */
    	GF_BGL_SYS_HEADER BGsys_data = {
      		GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BGMODE_0, GX_BG0_AS_2D,
    	};
    	GF_BGL_InitBG( &BGsys_data );
  	};
}

//------------------------------------------------------------------
/**
 * @brief	キャラクタ、パレットのマネージャー起動
 * @param	NONE
 * @return	NONE
 */
//------------------------------------------------------------------
static void InitCharPlttManager(void)
{
	// キャラクタマネージャー初期化
	{
		CHAR_MANAGER_MAKE cm = {
			CHAR_CONT_NUM,
			CHAR_VRAMTRANS_MAIN_SIZE,
			CHAR_VRAMTRANS_SUB_SIZE,
			HEAPID_POKETHLON,
		};
		InitCharManager(&cm);
	}
	// パレットマネージャー初期化
	InitPlttManager(PLTT_CONT_NUM, HEAPID_POKETHLON);

	// 読み込み開始位置を初期化
	CharLoadStartAll();
	PlttLoadStartAll();
}

//------------------------------------------------------------------
/**
 * @brief	OAMの初期化
 * @param	work			ワーク
 * @return	NONE
 */
//------------------------------------------------------------------
static void InitOAM(PKTHLN_POKE_SEL_WORK *work)
{
	int i;
	// OAMマネージャーの初期化
	NNS_G2dInitOamManagerModule();
	// 共有OAMマネージャ作成
	// レンダラ用OAMマネージャ作成
	// ここで作成したOAMマネージャをみんなで共有する
	REND_OAMInit(
			0, 126,		// メイン画面OAM管理領域
			0, 32,		// メイン画面アフィン管理領域
			1, 126,		// サブ画面OAM管理領域			通信アイコンだすので、1からスタート
			0, 32,		// サブ画面アフィン管理領域
			HEAPID_POKETHLON);
}

//----------------------------------------------------------------------------
/**
 *	@brief	Vブランク関数
 *
 *	@param	void * work 	ワーク
 *
 *	@return	none
 */
//-----------------------------------------------------------------------------
static void VBlankFunc( void * work )
{
   PKTHLN_POKE_SEL_WORK *wk = (PKTHLN_POKE_SEL_WORK *)work;

   POKESEL_DefaultVBlankCallFunc(wk->PokeSelPtr);
}

//----------------------------------------------------------------------------
/**
 *	@brief	ボックスのポケモンデータ取得
 *
 *	@param	*pBoxData		ボックスデータ
 *	@param	int inBoxNum	ボックスナンバー
 *	@param	int inIndex		インデックス
 *	@param	*outData 		データ格納バッファ
 *
 *	@return	BOOL			存在したか？		TRUE:存在した	FALSE:存在しない
 */
//-----------------------------------------------------------------------------
static BOOL GetBoxPokeData(void *pBoxData, const int inBoxNum, const int inIndex, BOX_POKE_DATA *outData )
{
	int exist;
	BOOL rc;
	BOX_DATA *box_data = (BOX_DATA*)pBoxData;
	POKEMON_PASO_PARAM* param = BOXDAT_GetPokeDataAddress( box_data, inBoxNum, inIndex );

	//存在を確認
	exist = PokePasoParaGet(param, ID_PARA_poke_exist, NULL);
	if (exist){
		//モンスターナンバー
		outData->MonsNo = PokePasoParaGet(param, ID_PARA_monsno, NULL);
		//個性乱数
		outData->PsnlRnd = PokePasoParaGet(param, ID_PARA_personal_rnd, NULL);
		//卵フラグ
		outData->Egg = PokePasoParaGet(param, ID_PARA_tamago_flag, NULL);
		//フォルム
		outData->Form = PokePasoParaGet(param, ID_PARA_form_no, NULL);
		//アイテム
		outData->Item = 0;	//ポケスロンでは、アイテムを表示しない
		//カスタムボール
		outData->Ball = 0;	//ポケスロンでは、カスタムボールを表示しない
		//ニックネーム
		PokePasoParaGet(param, ID_PARA_nickname, outData->NickName);
		//レア
		outData->Rare = PokePasoRareGet(param);
		//性別
		outData->Sex = PokePasoParaGet(param, ID_PARA_sex, NULL);
		rc = TRUE;
	}else{
		//モンスターナンバー
		outData->MonsNo = 0;
		//個性乱数
		outData->PsnlRnd = 0;
		//卵フラグ
		outData->Egg = 0;
		//フォルム
		outData->Form = 0;
		//アイテム
		outData->Item = 0;
		//カスタムボール
		outData->Ball = 0;
		//レア
		outData->Rare = 0;
		//性別
		outData->Sex = 0;
		rc = FALSE;
	}
	return rc;
}

//----------------------------------------------------------------------------
/**
 *	@brief	ボックスのポケモンデータ取得(アイコン展開用)
 *
 *	@param	*pBoxData		ボックスデータ
 *	@param	int inBoxNum	ボックスナンバー
 *	@param	int inIndex		インデックス
 *	@param	*outData 		データ格納バッファ
 *
 *	@return	BOOL			存在したか？		TRUE:存在した	FALSE:存在しない
 */
//-----------------------------------------------------------------------------
static BOOL GetBoxPokeData2(void *pBoxData, const int inBoxNum, const int inIndex, BOX_POKE_DATA *outData )
{
	int exist;
	BOOL rc;
	BOX_DATA *box_data = (BOX_DATA*)pBoxData;
	POKEMON_PASO_PARAM* param = BOXDAT_GetPokeDataAddress( box_data, inBoxNum, inIndex );

	//存在を確認
	exist = PokePasoParaGet(param, ID_PARA_poke_exist, NULL);
	if (exist){
		//モンスターナンバー
		outData->MonsNo = PokePasoParaGet(param, ID_PARA_monsno, NULL);
		//個性乱数
		outData->PsnlRnd = 0;
		//卵フラグ
		outData->Egg = PokePasoParaGet(param, ID_PARA_tamago_flag, NULL);
		//フォルム
		outData->Form = PokePasoParaGet(param, ID_PARA_form_no, NULL);
		//アイテム
		outData->Item = 0;	//ポケスロンでは、アイテムを表示しない
		//カスタムボール
		outData->Ball = 0;	//ポケスロンでは、カスタムボールを表示しない
		//レア
		outData->Rare = 0;
		//性別
		outData->Sex = 0;
		rc = TRUE;
	}else{
		//モンスターナンバー
		outData->MonsNo = 0;
		//個性乱数
		outData->PsnlRnd = 0;
		//卵フラグ
		outData->Egg = 0;
		//フォルム
		outData->Form = 0;
		//アイテム
		outData->Item = 0;
		//カスタムボール
		outData->Ball = 0;
		//レア
		outData->Rare = 0;
		//性別
		outData->Sex = 0;
		rc = FALSE;
	}
	return rc;
}

//----------------------------------------------------------------------------
/**
 *	@brief	ボックス名取得
 *
 *	@param	* msg			メッセージバッファ
 *	@param	*pBoxData		ボックスデータ
 *	@param	inBoxNumber		ボックスナンバー
 *
 *	@return	none
 */
//-----------------------------------------------------------------------------
static void GetBoxName(STRBUF * msg, void *pBoxData, int inBoxNumber)
{
	BOXDAT_GetBoxName( pBoxData, inBoxNumber, msg );
}

//----------------------------------------------------------------------------
/**
 *	@brief	選択結果セット
 *
 *	@param	*work			ポケモン選択ワークポインタ
 *	@param	*pLinkData		ポケスロンとの接続データポインタ
 *
 *	@return	none
 */
//-----------------------------------------------------------------------------
static void SetResultData(PKTHLN_POKE_SEL_WORK *work, PKTHLN_LINK_DATA *pLinkData)
{
	int i;

	pLinkData->SelectCancel = work->SelectCancel;

	if (work->SelectCancel){
		OS_Printf("キャンセルしたのでデータセットをスルー\n");
		return ;
	}

	//モンスターナンバーを取得
	for(i=0;i<POKEMON_SELECT_MAX;i++){
		if ( work->SelectResult[i].BoxIdx == MYPARTY_BOX ){
			POKEMON_PARAM* param;
			param = PokeParty_GetMemberPointer(SaveData_GetTemotiPokemon( pLinkData->Header->SaveData ),
												work->SelectResult[i].BoxPos);
			//モンスターナンバー
			pLinkData->CmnPlayerData.EntryData[i].MonsNo = PokeParaGet(param, ID_PARA_monsno, NULL);
			//個性乱数
			pLinkData->CmnPlayerData.EntryData[i].PsnlRnd = PokeParaGet(param, ID_PARA_personal_rnd, NULL);
			//フォルムナンバー
			pLinkData->CmnPlayerData.EntryData[i].Form = PokeParaGet(param, ID_PARA_form_no, NULL);
			//ニックネーム
			PokeParaGet( param, ID_PARA_nickname, pLinkData->CmnPlayerData.EntryData[i].NickName );
			//レア
			pLinkData->CmnPlayerData.EntryData[i].Rare = PokeRareGet(param);
			//性別
			pLinkData->CmnPlayerData.EntryData[i].Sex = PokeParaGet(param, ID_PARA_sex, NULL);
			//ポケスロン能力値を取得
			GetSpec( SaveData_GetTemotiPokemon( pLinkData->Header->SaveData ),
												work->SelectResult[i].BoxPos,
												&(pLinkData->CmnPlayerData.EntryData[i].Spec) );
#ifdef PM_DEBUG
			if (DebugPkthlnWk.SpecFlg){
				DebugGetSpec(&(pLinkData->CmnPlayerData.EntryData[i].Spec), i);
			}
#endif
		}else{
			BOX_POKE_DATA data;
			GetBoxPokeData(SaveData_GetBoxData( pLinkData->Header->SaveData ),
					work->SelectResult[i].BoxIdx, work->SelectResult[i].BoxPos, &data );
			//モンスターナンバー
			pLinkData->CmnPlayerData.EntryData[i].MonsNo = data.MonsNo;
			//個性乱数
			pLinkData->CmnPlayerData.EntryData[i].PsnlRnd = data.PsnlRnd;
			//フォルムナンバー
			pLinkData->CmnPlayerData.EntryData[i].Form = data.Form;
			//ニックネーム
			PM_strncpy( pLinkData->CmnPlayerData.EntryData[i].NickName, data.NickName, MONS_NAME_SIZE+EOM_SIZE );
			//レア
			pLinkData->CmnPlayerData.EntryData[i].Rare = data.Rare;
			//性別
			pLinkData->CmnPlayerData.EntryData[i].Sex = data.Sex;
			//ポケスロン能力値を取得
			{
				POKEMON_PASO_PARAM* param;
				param = BOXDAT_GetPokeDataAddress( SaveData_GetBoxData( pLinkData->Header->SaveData ),
												   work->SelectResult[i].BoxIdx,
												   work->SelectResult[i].BoxPos );
				GetSpecPPP(param, &(pLinkData->CmnPlayerData.EntryData[i].Spec));
			}
#ifdef PM_DEBUG
			if (DebugPkthlnWk.SpecFlg){
				DebugGetSpec(&(pLinkData->CmnPlayerData.EntryData[i].Spec), i);
			}
#endif
		}
	}
}

//----------------------------------------------------------------------------
/**
 *	@brief	ポケモンスペック取得
 *
 *  @param	*ppt			ポケパーティポインタ
 *	@param	inPos			パーティ内位置
 *	@param	outSpec			スペック格納バッファポインタ
 *
 *	@return	none
 */
//-----------------------------------------------------------------------------
static void GetSpec( POKEPARTY *ppt, const u8 inPos, POKE_SPEC *outSpec)
{
	PM_CONDITION pc;
	PM_PERFORMANCE pp;

	PokeParty_GetPokeCondition(ppt, &pc, inPos);
	GetPokePerformance(&pp,PokeParty_GetMemberPointer(ppt,inPos), &pc, HEAPID_POKETHLON);

	OS_Printf("手持ちポケモンスペック：pw=%d sp=%d jp=%d st=%d tq=%d\n",
			pp.power, pp.speed, pp.jump, pp.stamina, pp.technique);

	outSpec->Power = pp.power;
	outSpec->Speed = pp.speed;
	outSpec->Jump = pp.jump;
	outSpec->Stamina = pp.stamina;
	outSpec->Technique = pp.technique;

	//パフォーマンス値に対するコンディション値の補正コード -> poke_tool.h PERFORMANCE_DIFF_CODE型 090604 iwasawa
	outSpec->rev_power = pp.rev_power;
	outSpec->rev_speed = pp.rev_speed;
	outSpec->rev_jump = pp.rev_jump;
	outSpec->rev_stamina = pp.rev_stamina;
	outSpec->rev_technique = pp.rev_technique;
}

//----------------------------------------------------------------------------
/**
 *	@brief	ポケモンスペック取得
 *
 *  @param	param			ポケモンパラメータポインタ
 *	@param	outSpec			スペック格納バッファポインタ
 *
 *	@return	none
 */
//-----------------------------------------------------------------------------
static void GetSpecPPP( POKEMON_PASO_PARAM* param, POKE_SPEC *outSpec)
{
	PM_PERFORMANCE pp;

	GetPokePerformancePPP(&pp, param, NULL, HEAPID_POKETHLON);

	OS_Printf("ボックスポケモンスペック：pw=%d sp=%d jp=%d st=%d tq=%d\n",
			pp.power, pp.speed, pp.jump, pp.stamina, pp.technique);

	outSpec->Power = pp.power;
	outSpec->Speed = pp.speed;
	outSpec->Jump = pp.jump;
	outSpec->Stamina = pp.stamina;
	outSpec->Technique = pp.technique;

	//パフォーマンス値に対するコンディション値の補正コード -> poke_tool.h PERFORMANCE_DIFF_CODE型 090604 iwasawa
	outSpec->rev_power = pp.rev_power;
	outSpec->rev_speed = pp.rev_speed;
	outSpec->rev_jump = pp.rev_jump;
	outSpec->rev_stamina = pp.rev_stamina;
	outSpec->rev_technique = pp.rev_technique;
}

#ifdef PM_DEBUG
static void DebugGetSpec(POKE_SPEC *outSpec, const u8 inIdx)
{
	outSpec->Power = DebugPkthlnWk.Spec[inIdx][0];
	outSpec->Speed = DebugPkthlnWk.Spec[inIdx][1];
	outSpec->Jump = DebugPkthlnWk.Spec[inIdx][2];
	outSpec->Stamina = DebugPkthlnWk.Spec[inIdx][3];
	outSpec->Technique = DebugPkthlnWk.Spec[inIdx][4];

	//パフォーマンス値に対するコンディション値の補正コード -> poke_tool.h PERFORMANCE_DIFF_CODE型 090604 iwasawa
	outSpec->rev_power = 0;
	outSpec->rev_speed = 0;
	outSpec->rev_jump = 0;
	outSpec->rev_stamina = 0;
	outSpec->rev_technique = 0;

	OS_Printf("IDX %d デバッグポケモンスペック：pw=%d sp=%d jp=%d st=%d tq=%d\n", inIdx,
			outSpec->Power, outSpec->Speed, outSpec->Jump, outSpec->Stamina, outSpec->Technique);
}
#endif

//----------------------------------------------------------------------------
/**
 *	@brief	ポケモン最大スペック取得
 *
 *  @param	param			ポケモンパラメータポインタ
 *	@param	outSpec			スペック格納バッファポインタ
 *
 *	@return	none
 */
//-----------------------------------------------------------------------------
static void GetMaxSpecPPP( POKEMON_PASO_PARAM* param, POKE_SPEC *outSpec)
{
	PM_PERFORMANCE_BASE base;

	GetPokePerformanceBasePPP(param, &base);

	OS_Printf("ボックスポケモン最大スペック：pw=%d sp=%d jp=%d st=%d tq=%d\n",
			base.power.max, base.speed.max, base.jump.max, base.stamina.max, base.technique.max);

	outSpec->Power = base.power.max;
	outSpec->Speed = base.speed.max;
	outSpec->Jump = base.jump.max;
	outSpec->Stamina = base.stamina.max;
	outSpec->Technique = base.technique.max;
}

//----------------------------------------------------------------------------
/**
 *	@brief	ポケモン選択アプリコールバック関数
 *
 *  @param	inBoxIdx
 *	@param	inBoxPos
 *	@param	CallBackWk
 *
 *	@return	none
 */
//-----------------------------------------------------------------------------
static void	 CallbackFunc( int inBoxIdx, int inBoxPos, void *CallBackWk )
{
	u8 i;
	PSS_REDRAW_INFO info;
	PKTHLN_POKE_SEL_WORK *work;
	const CRS_ID crs_id[MEDAL_TYPE_MAX] = {
		CRS_ID_SPD,
		CRS_ID_POW,
		CRS_ID_TEQ,
		CRS_ID_STA,
		CRS_ID_JMP
	};

	OS_Printf("コールバックされた %d,%d\n",inBoxIdx,inBoxPos);

	work = (PKTHLN_POKE_SEL_WORK *)CallBackWk;

	if ( (inBoxIdx != -1)&&(inBoxPos != -1) ){
		info.ReDraw = PSS_REDRAW_UPDATE;
		//ポケ表示
		if (inBoxIdx == MYPARTY_BOX){	//手持ち
			POKEMON_PARAM* param;
			POKEPARTY *party;
			party = SaveData_GetTemotiPokemon( work->SaveData );
			param = PokeParty_GetMemberPointer( party, inBoxPos);
			//個性乱数
			info.PsnlRnd = PokeParaGet(param, ID_PARA_personal_rnd, NULL);
			//モンスターナンバー
			info.MonsNo = PokeParaGet(param, ID_PARA_monsno, NULL);
			//フォルムナンバー
			info.Form = PokeParaGet(param, ID_PARA_form_no, NULL);
			//ニックネーム
			PokeParaGet( param, ID_PARA_nickname, info.NickName );
			//レア
			info.Rare = PokeRareGet(param);
			//性別
			info.Sex = PokeParaGet(param, ID_PARA_sex, NULL);
			//ポケスロン能力値を取得
			{
				POKE_SPEC spec, max;
				PM_CONDITION pc;
				POKEMON_PASO_PARAM* param;
				POKEMON_PARAM *pp;
				pp = PokeParty_GetMemberPointer(party, inBoxPos);
				param = PPPPointerGet(pp);
				GetSpec(party, inBoxPos, &spec);
				GetMaxSpecPPP(param, &max);
				PokeParty_GetPokeCondition( party, &pc, inBoxPos);
				SetPkthlnParam(	&max, &spec, &pc, &info);
			}
			//メダル情報
			for (i=0;i<MEDAL_TYPE_MAX;i++){
				if ( PkthlnSv_IsMedal(PkthlnSv_GetSaveData(work->SaveData), crs_id[i], info.MonsNo ) ){
					info.Medal[i] = 1;
				}else{
					info.Medal[i] = 0;
				}
			}
			PkthSelSub_ReDraw(work->PssCntPtr, &info);
		}else{							//ボックス
			BOX_POKE_DATA data;
			GetBoxPokeData(SaveData_GetBoxData( work->SaveData ),
					inBoxIdx, inBoxPos, &data );
			//個性乱数
			info.PsnlRnd = data.PsnlRnd;
			//モンスターナンバー
			info.MonsNo = data.MonsNo;
			//フォルムナンバー
			info.Form = data.Form;
			//ニックネーム
			PM_strncpy( info.NickName, data.NickName, MONS_NAME_SIZE+EOM_SIZE );
			//レア
			info.Rare = data.Rare;
			//性別
			info.Sex = data.Sex;
			//ポケスロン能力値を取得
			{
				POKE_SPEC spec, max;
				PM_CONDITION pc;
				POKEMON_PASO_PARAM* param;
				param = BOXDAT_GetPokeDataAddress( SaveData_GetBoxData( work->SaveData ),
												   inBoxIdx, inBoxPos );
				GetSpecPPP(param, &spec);
				GetMaxSpecPPP(param, &max);
				MI_CpuClear8(&pc, sizeof(PM_CONDITION));
				SetPkthlnParam(	&max, &spec, &pc, &info);

			}
			//メダル情報
			for (i=0;i<MEDAL_TYPE_MAX;i++){
				if ( PkthlnSv_IsMedal(PkthlnSv_GetSaveData(work->SaveData), crs_id[i], info.MonsNo ) ){
					info.Medal[i] = 1;
				}else{
					info.Medal[i] = 0;
				}
			}
			PkthSelSub_ReDraw(work->PssCntPtr, &info);
		}
	}else{
		//情報なし
		info.ReDraw = PSS_REDRAW_CLEAR;
		PkthSelSub_ReDraw(work->PssCntPtr, &info);
	}
}

//----------------------------------------------------------------------------
/**
 *	@brief	パラメータセット
 *
 *  @param	inMax		最大スペック
 *	@param	inSpec		現在スペック
 *	@param	inCnd		コンディション
 *	@param	outInfo		格納バッファ
 *
 *	@return	none
 */
//-----------------------------------------------------------------------------
static void SetPkthlnParam(	const POKE_SPEC *inMax, const POKE_SPEC *inSpec,
							const PM_CONDITION *inCnd, PSS_REDRAW_INFO *outInfo)
{
	//パワー
	outInfo->Param[0].UpDown = GetPerformanceMeterInfo(
			outInfo->Param[0].Stars, inMax->Power, inSpec->Power, inSpec->rev_power, inCnd->power );
	//スタミナ
	outInfo->Param[1].UpDown = GetPerformanceMeterInfo(
			outInfo->Param[1].Stars, inMax->Stamina, inSpec->Stamina, inSpec->rev_stamina, inCnd->stamina );
	//テクニック
	outInfo->Param[2].UpDown = GetPerformanceMeterInfo(
			outInfo->Param[2].Stars, inMax->Technique, inSpec->Technique, inSpec->rev_technique, inCnd->technique );
	//ジャンプ
	outInfo->Param[3].UpDown = GetPerformanceMeterInfo(
			outInfo->Param[3].Stars, inMax->Jump, inSpec->Jump, inSpec->rev_jump, inCnd->jump );
	//スピード
	outInfo->Param[4].UpDown = GetPerformanceMeterInfo(
			outInfo->Param[4].Stars, inMax->Speed, inSpec->Speed, inSpec->rev_speed, inCnd->speed );
}